package com.briup.smartcity_group1.web.interceptor;

import com.briup.smartcity_group1.utils.JwtUtils;
import com.briup.smartcity_group1.web.mapping.prefix.AuthPackageURIPrefix;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Set;

import com.briup.smartcity_group1.context.TokenContext;

/** token拦截器，检查token
 * @author congee(congee02 @ 163.com)
 * @date 1/4/2023 4:29 PM
 */
@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {

    /**
     * token 黑名单，{@link TokenContext#tokenBlackList()}
     */
    @Resource(type = Set.class, name = "tokenBlackList")
    private Set<String> tokenBlackList;

    /**
     * 若没有合法 token 或 token 在黑名单中 {@link TokenContext#tokenBlackList()} ，拦截 uri 前缀为 auth 的请求
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  chosen handler to execute, for type and/or instance evaluation
     * @return {@code true} if the execution chain should proceed with the
     * next interceptor or the handler itself. Else, DispatcherServlet assumes
     * that this interceptor has already dealt with the response itself.
     * @throws Exception in case of errors
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String uri = request.getRequestURI();

        String token = request.getHeader("Authorization");

        // uri 以 auth 为前缀，则需要 token 验证
        if (uri.startsWith("/" + AuthPackageURIPrefix.AUTH_URI_PREFIX)) {
            if (token == null
                    || ! JwtUtils.checkSign(token)
                    || tokenBlackList.contains(token)) {
                log.warn("token 无效，拒绝放行: {}", uri);
                return false;
            }
        }

        log.info("有效的 token: {}", token);
        log.info("允许放行: {}", uri);

        return true;
    }
}
